/*
 * Copyright 2013-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.cloud.gateway.discovery;

import java.util.ArrayList;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.core.style.ToStringCreator;

@ConfigurationProperties("spring.cloud.gateway.discovery.locator")
public class DiscoveryLocatorProperties {

	/**
	 * Flag that enables DiscoveryClient gateway integration.
	 * 标记是否启用 DiscoveryClient 网关集成。如果设置为 true，则会启用基于服务发现的服务路由。
	 * */
	private boolean enabled = false;

	/**
	 * The prefix for the routeId, defaults to discoveryClient.getClass().getSimpleName()
	 * + "_". Service Id will be appended to create the routeId.
	 * <p>
	 *     路由 ID 的前缀，默认情况下使用 discoveryClient.getClass().getSimpleName() + "_" 加上服务 ID 来创建路由 ID。
	 *     此属性允许你自定义这个前缀。
	 * </p>
	 */
	private String routeIdPrefix;

	/**
	 * SpEL expression that will evaluate whether to include a service in gateway
	 * integration or not, defaults to: true.
	 * <p>
	 *     一个 SpEL（Spring Expression Language）表达式，用于评估是否应将某个服务包含在网关集成中。默认值为 "true"，即所有服务都将被包含。
	 * </p>
	 */
	private String includeExpression = "true";

	/**
	 * SpEL expression that create the uri for each route, defaults to: 'lb://'+serviceId.
	 * <p>
	 *  另一个 SpEL 表达式，用于生成每个路由的目标 URI。默认值为 'lb://'+serviceId，这意味着它将尝试通过负载均衡器访问指定的服务 ID
	 * </p>
	 */
	private String urlExpression = "'lb://'+serviceId";

	/**
	 * Option to lower case serviceId in predicates and filters, defaults to false. Useful
	 * with eureka when it automatically uppercases serviceId. so MYSERIVCE, would match
	 * /myservice/**
	 * <p>
	 *  是否将服务 ID 转换为小写以匹配路径中的服务名。这对于 Eureka 用户特别有用，因为 Eureka 可能会自动将服务 ID 大写。例如，如果你的服务 ID 是 MYSERVICE，那么 /myservice/** 将能够匹配到这个服务。
	 * </p>
	 */
	private boolean lowerCaseServiceId = false;

	/**
	 * 定义了应用于路由的一系列断言条件。这些断言决定了哪些请求应该被路由到对应的服务。
	 */
	private List<PredicateDefinition> predicates = new ArrayList<>();

	/**
	 * 定义了一系列过滤器，可以在请求到达目标服务之前或之后对请求进行修改。这可以包括添加/删除请求头、修改请求体等操作。
	 */
	private List<FilterDefinition> filters = new ArrayList<>();

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public String getRouteIdPrefix() {
		return routeIdPrefix;
	}

	public void setRouteIdPrefix(String routeIdPrefix) {
		this.routeIdPrefix = routeIdPrefix;
	}

	public String getIncludeExpression() {
		return includeExpression;
	}

	public void setIncludeExpression(String includeExpression) {
		this.includeExpression = includeExpression;
	}

	public String getUrlExpression() {
		return urlExpression;
	}

	public void setUrlExpression(String urlExpression) {
		this.urlExpression = urlExpression;
	}

	public boolean isLowerCaseServiceId() {
		return lowerCaseServiceId;
	}

	public void setLowerCaseServiceId(boolean lowerCaseServiceId) {
		this.lowerCaseServiceId = lowerCaseServiceId;
	}

	public List<PredicateDefinition> getPredicates() {
		return predicates;
	}

	public void setPredicates(List<PredicateDefinition> predicates) {
		this.predicates = predicates;
	}

	public List<FilterDefinition> getFilters() {
		return filters;
	}

	public void setFilters(List<FilterDefinition> filters) {
		this.filters = filters;
	}

	@Override
	public String toString() {
		return new ToStringCreator(this).append("enabled", enabled)
			.append("routeIdPrefix", routeIdPrefix)
			.append("includeExpression", includeExpression)
			.append("urlExpression", urlExpression)
			.append("lowerCaseServiceId", lowerCaseServiceId)
			.append("predicates", predicates)
			.append("filters", filters)
			.toString();
	}

}
